﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HU8.Helpers.Base;
using System.IO;
using System.Xml.Linq;
using System.Xml;
using System.Security.AccessControl;
using System.Security.Principal;

namespace HU8.Helpers.Files
{
    /// <summary>
    /// InstallHelper用来安装网站所需的数据库，文件
    /// 备份，升级等
    /// </summary>
    public class InstallHelper
    {
        /// <summary>
        /// 安装数据库
        /// </summary>
        public static JsonResponse InstallDatabase(string server, string database, string userName, string password, string installSqlPath)
        {
            JsonResponse response = new JsonResponse();
            string testConnectionString = DatabaseHelper.BuildConnectionString(server, "", userName, password);
            JsonResponse connectionResponse = DatabaseHelper.TestDBConnection(testConnectionString);
            response.message = string.Format("<h2>数据库链接测试</h2><p>{0}</p>", connectionResponse.message);
            if (connectionResponse.success)
            {
                //如果连接成功，显示一下数据库版本
                response.message += string.Format("<p>SQL数据库版本：{0}</p>", DatabaseHelper.GetSqlVersion(testConnectionString));

                //数据库名称不能为空
                if (string.IsNullOrEmpty(database))
                {
                    response.message += "<p>数据库名称不能为空</p>";
                    response.success = false;
                    return response;
                }

                //新建数据库
                JsonResponse dbCreationResponse = DatabaseHelper.CreateDatabase(database, testConnectionString);
                response.message += string.Format("<p>{0}</p>", dbCreationResponse.message);
                if (dbCreationResponse.success)
                {
                    //安装数据库
                    response.message += string.Format("<h2>安装数据库结构，以及数据</h2>");
                    string connectionString = DatabaseHelper.BuildConnectionString(server, database, userName, password);
                    JsonResponse dbInstall = DatabaseHelper.RunScriptFile(connectionString, installSqlPath); //指定了数据库
                    response.message += string.Format("<textarea rows='10' cols='50'>{0}</textarea>", dbInstall.message);
                    response.success = dbInstall.success;
                }
                else
                {
                    response.success = false;
                    response.message += "<p>错误：无法创建SQL Server数据库[" + database + "]</p>";
                }
            }
            else
            {
                //数据库链接失败，安装失败
                response.success = connectionResponse.success;
            }
            return response;
        }

        /// <summary>
        /// 备份数据库
        /// </summary>
        /// <returns></returns>
        public static string BackupDatabase()
        {
            return "";
        }

        /// <summary>
        /// 回复数据库
        /// </summary>
        /// <returns></returns>
        public static string RestoreDatabase()
        {
            return null;
        }

        /// <summary>
        /// 备份模板
        /// </summary>
        /// <param name="folder"></param>
        /// <param name="dest"></param>
        /// <returns></returns>
        public static void BackupFolder(string folder, string dest)
        {
            ZipHelper.GenerateZipFile(new List<string>() { folder }, dest, "", "", false);
        }

        /// <summary>
        /// 安装模板
        /// </summary>
        /// <param name="zipFile"></param>
        /// <param name="destFolder"></param>
        public static void InstallFolder(string zipFile, string destFolder, string backupFolder)
        {
            if (!Directory.Exists(destFolder))
            {
                Directory.CreateDirectory(destFolder);
            }
            DirectoryInfo di = new DirectoryInfo(destFolder);
            backupFolder = Path.Combine(backupFolder, string.Format("[{0}]BACKUP-{1}.zip", di.Name, DateTime.Now.ToString("yyyyMMddhhmmss")));
            BackupFolder(destFolder, backupFolder);
            ZipHelper.UnzipFile(zipFile, destFolder, true);
        }

        /// <summary>
        /// 安装系统文件
        /// 1. 将系统文件备份
        /// 2. 删除原有系统文件
        /// 3. 添加原有系统文件
        /// </summary>
        public static JsonResponse InstallSystemFiles(string zipFile, string dest, string backupPath, string connectionString)
        {
            //卸载现有系统
            string tempBackup = UninstallSystemFiles(dest, backupPath);
            JsonResponse response = ZipHelper.UnzipFile(zipFile, dest, true);//解压文件夹，覆盖
            if (response.success)
            {
                //创建文件夹
                FileHelper.CreateFolder(dest, "Content/site");
                FileHelper.CreateFolder(dest, "Templates");
                FileHelper.CreateFolder(dest, "Templates/template");

                //如果connection string是空的话，不更新
                if (!string.IsNullOrEmpty(connectionString))
                {
                    //更新Web.config
                    if (File.Exists(Path.Combine(dest, "web.config")))
                    {
                        File.Delete(Path.Combine(dest, "web.config"));
                    }
                    string configFile = Path.Combine(dest, "web.config.txt");
                    response.message += UpdateWebConfig(configFile, connectionString).message;
                }
                //将bin_temp里的内容，剪切到bin里
                FileHelper.Cut(Path.Combine(dest, "bin_temp"), Path.Combine(dest, "bin"));
                if (Directory.Exists(Path.Combine(dest, "bin_temp")))
                {
                    Directory.Delete(Path.Combine(dest, "bin_temp"), true); //删除bin_temp文件夹
                }
                if (File.Exists(Path.Combine(dest, "Default.aspx")))
                {
                    File.Delete(Path.Combine(dest, "Default.aspx"));//删除掉主目录的Default.aspx导航文件
                }
            }
            else
            {
                //ROLLBACK
                FileHelper.DeleteFolderContents(dest, "", BaseHelper.INSTALL_EXCEPTIONS);//删除可能已经安装好的文件
                ZipHelper.UnzipFile(tempBackup, dest, true); //恢复原来的文件
            }
            return response;
        }

        public static JsonResponse UpdateWebConfig(string configFile, string connectionString)
        {
            JsonResponse response = new JsonResponse();
            try
            {
                if (File.Exists(configFile))
                {

                    //更新Web.config文件
                    XmlDocument doc = new XmlDocument();
                    doc.Load(configFile);
                    XmlNode connectionStringsNode = doc.SelectSingleNode("/configuration/connectionStrings");
                    XmlNode connectionStringNode = connectionStringsNode.SelectSingleNode("add[@name='CMSConnectionString']");
                    if (connectionStringNode == null)
                    {//不存在就创建一个.    chiron 2011-9-27
                        connectionStringNode = doc.CreateElement("add");
                        var nameAttr = doc.CreateAttribute("name");
                        nameAttr.Value = "CMSConnectionString";
                        connectionStringNode.Attributes.Append(nameAttr);

                        var providerNameAttr = doc.CreateAttribute("providerName");
                        providerNameAttr.Value = "System.Data.SqlClient";
                        connectionStringNode.Attributes.Append(providerNameAttr);

                        connectionStringNode.Attributes.Append(doc.CreateAttribute("connectionString"));
                        connectionStringsNode.AppendChild(connectionStringNode);
                    }
                    connectionStringNode.Attributes["connectionString"].Value = connectionString;
                    //开启自定义错误页面
                    var webNode = doc.SelectSingleNode("/configuration/system.web");
                    XmlNode customErrorNode = webNode.SelectSingleNode("customErrors");
                    if (customErrorNode == null)
                    {
                        customErrorNode = doc.CreateElement("customErrors");
                        customErrorNode.Attributes.Append(doc.CreateAttribute("mode"));
                        webNode.AppendChild(customErrorNode);
                    }
                    customErrorNode.Attributes["mode"].Value = "On";
                    //关闭Debug模式
                    XmlNode compliationNode = webNode.SelectSingleNode("compilation");
                    if (compliationNode.Attributes["debug"] == null) compliationNode.Attributes.Append(doc.CreateAttribute("debug"));
                    compliationNode.Attributes["debug"].Value = "false";
                    doc.Save(configFile);

                    //将Web.config.txt
                    FileHelper.Rename(configFile, "web.config");
                }
                response.success = true;
                response.message = "<p>web.config文件更新成功</p>";
            }
            catch (Exception ex)
            {
                response.message = "<p class='error'>Web.config文件更新失败：" + ex.Message + "</p>";
                response.success = false;
            }
            return response;
        }

        /// <summary>
        /// 卸载现有系统
        /// </summary>
        /// <param name="dest"></param>
        /// <param name="backupPath"></param>
        public static string UninstallSystemFiles(string dest, string backupPath)
        {
            //先备份
            string tempBackup = BackupSystemFiles(dest, backupPath);
            //1.删除网站文件
            FileHelper.DeleteFolderContents(dest, "", BaseHelper.INSTALL_EXCEPTIONS);  //除了一部分文件之外，其它的删除
            //2.删除数据库
            return tempBackup;
        }

        /// <summary>
        /// 备份系统文件
        /// </summary>
        /// <returns></returns>
        public static string BackupSystemFiles(string dest, string backupPath)
        {
            string tempFolder = Path.Combine("Temp" + Guid.NewGuid().ToString());
            FileHelper.CreateFolder(backupPath, tempFolder);
            tempFolder = Path.Combine(backupPath, tempFolder);

            //1.先压缩到web.zip
            string zipBackup = Path.Combine(tempFolder, "web.zip"); //先压缩到web.zip
            ZipHelper.GenerateZipFile(new List<string>() { dest }, zipBackup, "", BaseHelper.INSTALL_EXCEPTIONS, false);

            //2.再压缩到具体的文件
            string tempBackup = Path.Combine(backupPath, string.Format("Fullsite-Backup-{0}.zip", DateTime.Now.ToString("yyyy-MM-dd-hh-mm-ss"))); //临时备份文件
            ZipHelper.GenerateZipFile(new List<string>() { zipBackup }, tempBackup, "", BaseHelper.INSTALL_EXCEPTIONS, false);

            //删除临时文件夹
            Directory.Delete(tempFolder, true);
            return tempBackup;
        }

        public static string RestoreSystemFiles()
        {
            return "";
        }

        /// <summary>
        /// 安装模板
        /// </summary>
        /// <returns></returns>
        public static string InstallTemplates()
        {
            return "";
        }

        /// <summary>
        /// 恢复模板
        /// </summary>
        public static void RestoreTemplates()
        {
        }
        /// <summary>
        /// 初始化用户文件夹
        /// </summary>
        public static string InitDirectories()
        {

            return "";
        }

    }
}
